home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / gcc / ixemulsrc.lha / ixemul-41.4 / library / ix_sleep.c < prev    next >
C/C++ Source or Header  |  1995-09-27  |  4KB  |  168 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *  Portions Copyright (C) 1994 Rafael W. Luebbert
  5.  *
  6.  *  This library is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU Library General Public
  8.  *  License as published by the Free Software Foundation; either
  9.  *  version 2 of the License, or (at your option) any later version.
  10.  *
  11.  *  This library is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  *  Library General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU Library General Public
  17.  *  License along with this library; if not, write to the Free
  18.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  *  $Id: ix_sleep.c,v 1.4 1994/06/19 15:13:19 rluebbert Exp $
  21.  *
  22.  *  $Log: ix_sleep.c,v $
  23.  *  Revision 1.4  1994/06/19  15:13:19  rluebbert
  24.  *  *** empty log message ***
  25.  *
  26.  * 
  27.  * 
  28.  */
  29.  
  30. #define KERNEL
  31. #include "ixemul.h"
  32. #include "kprintf.h"
  33.  
  34. #define __time_req (p->u_time_req)
  35. #define __tport    (p->u_sync_mp)
  36.  
  37. extern struct ixemul_base *ixemulbase;
  38.  
  39. /* this is the `message' we queue on the sleep queues. */
  40. struct sleep_msg {
  41.   struct MinNode     sm_node;
  42.   short            sm_signal;
  43.   struct Task*        sm_sigtask;
  44.   u_int            sm_waitchan;
  45. };
  46.  
  47.  
  48. static inline u_short
  49. ix_hash (u_int waitchan)
  50. {
  51.   unsigned short res;
  52.  
  53.   res = (waitchan >> 16) ^ (waitchan & 0xffff);
  54.   res %= IX_NUM_SLEEP_QUEUES;
  55.   return res; 
  56. }
  57.  
  58. int
  59. tsleep(caddr_t waitchan, char *wmesg, int timo)
  60. {
  61.   /* we run in the context of the calling task, we generate a sleep msg and
  62.    * add it to the right sleep queue. wakeup() will do the rest.
  63.    */
  64.   struct sleep_msg sm;
  65.   struct MinList *the_list;
  66.   u_int wait_sigs;
  67.   int res = -1;
  68.   struct timeval tv;
  69.   struct user *p = &u;
  70.  
  71.  
  72.   if (CURSIG (& u))
  73.     {
  74.       errno = EINTR;
  75.       KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  76.       return -1;
  77.     }
  78.  
  79.   sm.sm_sigtask = FindTask (0);
  80.   sm.sm_waitchan = waitchan;
  81.  
  82.   u.p_stat = SSLEEP;    /* so that machdep.c can interrupt us */
  83.   u.p_wchan = (caddr_t) waitchan;
  84.   u.p_wmesg = wmesg;
  85.   the_list = & ixemulbase->ix_sleep_queues [ix_hash (waitchan)];
  86.   
  87.   sm.sm_signal = u.u_sleep_sig;
  88.  
  89.   wait_sigs =  (1<< sm.sm_signal) | SIGBREAKF_CTRL_C;
  90.   
  91.   if (timo)
  92.     {
  93.       __time_req->tr_time.tv_sec = timo % 60;
  94.       __time_req->tr_time.tv_usec = timo / 60;
  95.       __time_req->tr_node.io_Command = TR_ADDREQUEST;
  96.       SetSignal (0, 1 << __tport->mp_SigBit);
  97.       SendIO((struct IORequest *)__time_req);
  98.       wait_sigs |= 1 << __tport->mp_SigBit;
  99.     }
  100.  
  101.   Disable ();
  102.   AddTail ((struct List *) the_list, (struct Node *) &sm);
  103.  
  104.   /* this will break the Disable () and reestablish it afterwards */
  105.   res = Wait (wait_sigs);
  106.   /* this conversion is inhibited in the Launch handler as long as we're
  107.      in SSLEEP state. Since the SetSignal() below will remove all traces
  108.      of a perhaps present SIGBREAKF_CTRL_C, we'll have to do the conversion
  109.      here ourselves */
  110.   if (((u.p_sigignore & sigmask(SIGMSG)) || !(u.p_sigcatch & sigmask(SIGMSG)))
  111.       && (res & SIGBREAKF_CTRL_C))
  112.     _psignalgrp((struct Process *)FindTask(0), SIGINT);
  113.   SetSignal (0, res);
  114.   res = CURSIG (&u) ? -1 : 0;
  115.  
  116.   Remove ((struct Node *) &sm);
  117.   Enable ();
  118.  
  119.   if (timo)
  120.     {
  121.       if (! CheckIO ((struct IORequest *)__time_req))
  122.         AbortIO ((struct IORequest *)__time_req);
  123.       WaitIO ((struct IORequest *)__time_req);
  124.     }
  125.  
  126.   u.p_wchan = 0;
  127.   u.p_wmesg = 0;
  128.   u.p_stat = SRUN;
  129.   errno = res == 0 ? 0 : EINTR;
  130.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  131.   return res;
  132. }
  133.  
  134. int
  135. ix_sleep (caddr_t chan, char *wmesg)
  136. {
  137.   return tsleep (chan, wmesg, 0);
  138. }
  139.  
  140.  
  141. /*
  142.  * ix_wakeup() can be called from an interrupt (and is called that way;-))
  143.  */
  144.  
  145. void
  146. ix_wakeup (u_int waitchan)
  147. {
  148.   struct MinList *the_list = & ixemulbase->ix_sleep_queues[ix_hash (waitchan)];
  149.   struct sleep_msg *sm, *nsm;
  150.   
  151.   Disable ();
  152.  
  153.   for (sm  = (struct sleep_msg *)the_list->mlh_Head;
  154.        nsm = (struct sleep_msg *)sm->sm_node.mln_Succ;
  155.        sm  = nsm)
  156.     if (sm->sm_waitchan == waitchan)
  157.       Signal (sm->sm_sigtask, 1 << sm->sm_signal);
  158.  
  159.   Enable ();
  160. }
  161.  
  162.  
  163. void
  164. wakeup (u_int waitchan)
  165. {
  166.   ix_wakeup (waitchan);
  167. }
  168.